/// <reference path="../Interface.ts" />
/// <reference path="../Emitter.ts" />

namespace egret.socketio.engine {
    
    /**
    * Transport
    */
    export abstract class Transport extends Emitter {

        public opts: TransportUri;

        protected readyState: _emReadyState = _emReadyState.CLOSED;
        public writable: boolean = true;
        public name: string;
        public pause: Function;
        
        constructor(opts: TransportUri) {
            super();
            this.opts = opts.clone();
            // this.path = opts.path;
            // this.hostname = opts.hostname;
            // this.port = opts.port;
            // this.secure = opts.secure;
            // this.query = opts.query || new Map();
            // this.timestampParam = opts.timestampParam;
            // this.timestampRequests = opts.timestampRequests;

        }

        protected onError(msg: string): Transport {
            this.emit(_emEvent.EVENT_ERROR);
            return this;
        }

        public open(): Transport {

            if (this.readyState === _emReadyState.CLOSED ||
                this.readyState === null) {
                this.readyState = _emReadyState.OPENING;
                this.doOpen();
            }
            return this;
        }

        public close(): Transport {
            if (this.readyState === _emReadyState.OPENING ||
                this.readyState === _emReadyState.OPEN) {
                this.doClose();
                this.onClose();
            }

            return this;
        }

        public send(packets: Packet[]): void {
            if (this.readyState === _emReadyState.OPEN) {
                this.write(packets);
            }
        }

        protected onOpen(): void {
            this.readyState = _emReadyState.OPEN;
            this.writable = true;
            this.emit(_emEvent.EVENT_OPEN);
        }

        protected onData(data: any): void {
            this.onPacket( Parser.decodePacket(data, false));
        }

        protected onPacket(packet: Packet): void {
            this.emit(_emEvent.EVENT_PACKET, packet);
        }

        protected onClose(): void {
            this.readyState = _emReadyState.CLOSED;
            this.emit(_emEvent.EVENT_CLOSE);
        }

        protected abstract write(packets: Packet[]): void;
        protected abstract doOpen(): void;
        protected abstract doClose(): void;
    }
}